/*
 * 文件名： CiticExpayBankServiceImpl.java
 * 
 * 工程名称: bis-bank-citic
 *
 * Gopay
 *
 * 创建日期： 2016年6月17日
 *
 * Copyright(C) 2016, by www.gopay.com.cn Inc.All rights reserved.
 *
 * 原始作者: 宣广海
 *
 */
package com.gopay.bis.citic.expay.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.bis.citic.expay.operation.CiticExpayCertHelper;
import com.gopay.bis.citic.expay.operation.SocketTransport;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.ExPayBaseMessage;
import com.gopay.common.domain.bank.citic.expay.CiticExpay;
import com.gopay.common.domain.bank.citic.expay.CiticExpayErrorMessage;
import com.gopay.common.domain.bank.citic.expay.CiticExpayResMessage;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.bank.businesses.ExPayService;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

/**
 * 中信银行快捷支付报文交互处理类
 *
 * @author 宣广海
 *
 * @version
 *
 * @since 2016年6月17日
 */
public class CiticExpayBankServiceImpl implements ExPayService {
	/**
	 * 日志对象
	 */
	private static Logger logger = LoggerFactory.getLogger(CiticExpayBankServiceImpl.class);

	/**
	 * 注入对象
	 */
	private CiticExpayCertHelper citicExpayCertHelper;
	private SocketTransport socketTransport;

	@Override
	public Object sign(BaseMessage baseMsg) throws GopayException {
		CiticExpay citicExpay = (CiticExpay) baseMsg;
		CiticExpayResMessage payResMessage = null;
		try {
			/**
			 * 签名
			 */
			byte[] signStr = citicExpayCertHelper.sign(citicExpay);

			/**
			 * 发送鉴权报文到中信外联平台
			 */
			byte[] returnStr =  socketTransport.socketTranspotMessage(signStr);

			/**
			 *  解密并且验签
			 */
			String plainMessage=(String)citicExpayCertHelper.verify(citicExpay,returnStr);
			
			payResMessage = (CiticExpayResMessage) parseRes(plainMessage);

			/**
			 * 快捷支付返回异常报文对象
			 */
			CiticExpayErrorMessage errorMessage = payResMessage.getExpayMessage().getErrorMessage();

			if (null == errorMessage) {
				payResMessage.setSuccess(true);
			}

		} catch (GopayException gex) {
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E6076);
		} catch (Exception ex) {
			logger.error("中信银行快捷支付签约异常。" + ex);
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E6076);
		}
		return payResMessage;
	}

	@Override
	public ExPayBaseMessage payment(BaseMessage baseMsg) throws GopayException {

		CiticExpay citicExpay = (CiticExpay) baseMsg;
		CiticExpayResMessage payResMessage = null;

		String bankBusProd = citicExpay.getBankBusProd().value;
		try {

			/**
			 * 中信银行直连快捷支付只有借记卡
			 */
			if ((BisBankBusinessProd._15.value).equals(bankBusProd)) {
				// 支付请求报文签名及加密
				byte[] signStr = citicExpayCertHelper.sign(citicExpay);
				// 发送支付报文到中信外联平台
				byte[] returnStr = socketTransport.socketTranspotMessage(signStr);
				// 解密并且验签
				String plainMessage=(String)citicExpayCertHelper.verify(citicExpay,returnStr);
				//转XML报文到对象
				payResMessage = (CiticExpayResMessage) parseRes(plainMessage);
				payResMessage.setSuccess(true);
			} else {
				throw new GopayException(ProcCodeConstants.PROC_CODE_100E7014);
			}
			/**
			 * 快捷支付返回异常报文对象
			 */
			CiticExpayErrorMessage errorMessage = payResMessage.getExpayMessage().getErrorMessage();
			if(errorMessage!=null){
				// add by wangjiqing 2017-12-27
				payResMessage.setBankRetCode(errorMessage.getRetCode());
			}

		} catch (GopayException gex) {
			throw new GopayException(gex.getErrCode());
		} catch (Exception ex) {
			logger.error("中信银行快捷支付异常。" + ex);
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E6057);
		}
		return payResMessage;

	}


	@Override
	public Object queryOrder(BaseMessage baseMsg) throws GopayException {

		CiticExpay citicExpay = (CiticExpay) baseMsg;
		CiticExpayResMessage payResMessage = null;
		try {

			byte[] signStr = citicExpayCertHelper.sign(citicExpay);

			/**
			 * 发送单笔查询报文到中信外联平台
			 */
			byte[] returnStr =socketTransport.socketTranspotMessage(signStr);
			
			/**
			 *  解密并且验签
			 */
			String plainMessage=(String)citicExpayCertHelper.verify(citicExpay,returnStr);			

			payResMessage = (CiticExpayResMessage) parseRes(plainMessage);

			/**
			 * 快捷支付返回异常报文对象
			 */
			CiticExpayErrorMessage errorMessage = payResMessage.getExpayMessage().getErrorMessage();

			if (null == errorMessage) {
				payResMessage.setSuccess(true);
			} else {
				//add by liuyu, 20170803, 快捷API失败通知
				payResMessage.setBankRetCode(errorMessage.getRetCode());
			}

		} catch (GopayException gex) {
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E6058);
		} catch (Exception ex) {
			logger.error("中信银行快捷支付查询订单异常。" + ex);
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E6058);
		}
		return payResMessage;
	}

	@Override
	public Object certification(BaseMessage baseMsg) throws GopayException {

		CiticExpay citicExpay = (CiticExpay) baseMsg;
		CiticExpayResMessage payResMessage = new CiticExpayResMessage();
		try {
			
			byte[] signStr = citicExpayCertHelper.sign(citicExpay);

			/**
			 * 发送鉴权报文到中信外联平台
			 */
			byte[] returnStr = socketTransport.socketTranspotMessage(signStr);
			/**
			 *  解密并且验签
			 */
			String plainMessage=(String)citicExpayCertHelper.verify(citicExpay,returnStr);	
			
			payResMessage = (CiticExpayResMessage) parseRes(plainMessage);

			/**
			 * 快捷支付返回异常报文对象
			 */
			CiticExpayErrorMessage errorMessage = payResMessage.getExpayMessage().getErrorMessage();

			if (null == errorMessage) {
				payResMessage.setSuccess(true);
			}

		} catch (GopayException gex) {
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E6076);
		} catch (Exception ex) {
			logger.error("中信银行快捷支付鉴权异常。" + ex);
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E6076);
		}
		return payResMessage;
	}
	/**
	 * 
	 * 功能描述：转化XML报文到对象
	 *
	 * @param resStr
	 * @return
	 * 
	 * @author 宣广海
	 *
	 * @since 2016年6月27日
	 *
	 * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
	 */
	public CiticExpayResMessage parseRes(String resStr) {
		XStream xstream = new XStream(new DomDriver());
		xstream.autodetectAnnotations(true);
		xstream.processAnnotations(CiticExpayResMessage.class);
		xstream.ignoreUnknownElements();
		CiticExpayResMessage resData = (CiticExpayResMessage) xstream.fromXML(resStr);

		return resData;
	}

	@Override
	public Object sendSms(BaseMessage baseMsg) throws GopayException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object checkSms(BaseMessage baseMsg) throws GopayException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object queryCvn(BaseMessage baseMsg) throws GopayException {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public Object refund(BaseMessage baseMsg) throws GopayException {
	    CiticExpay citicExpay = (CiticExpay) baseMsg;
        CiticExpayResMessage payResMessage = null;
        try {

            // 支付请求报文签名及加密
            byte[] signStr = citicExpayCertHelper.sign(citicExpay);
            // 发送支付报文到中信外联平台
            byte[] returnStr = socketTransport.socketTranspotMessage(signStr);
            // 解密并且验签
            String plainMessage = (String) citicExpayCertHelper.verify(citicExpay, returnStr);
            // 转XML报文到对象
            payResMessage = (CiticExpayResMessage) parseRes(plainMessage);

            /**
             * 快捷支付返回异常报文对象
             */
            CiticExpayErrorMessage errorMessage = payResMessage.getExpayMessage().getErrorMessage();

            if (null == errorMessage) {
                payResMessage.setSuccess(true);
            }

        } catch (GopayException gex) {
            throw new GopayException(gex.getErrCode());
        } catch (Exception ex) {
            logger.error("中信银行快捷支付异常。" + ex);
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E6057);
        }
        return payResMessage;
	}

	@Override
	public Object verify(BaseMessage baseMsg) throws GopayException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object treatyQuery(BaseMessage baseMsg) throws GopayException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object cancel(BaseMessage baseMsg) throws GopayException {
		// TODO Auto-generated method stub
		return null;
	}

	

	public SocketTransport getSocketTransport() {
		return socketTransport;
	}

	public void setSocketTransport(SocketTransport socketTransport) {
		this.socketTransport = socketTransport;
	}

	@Override
	public Object signQuery(BaseMessage baseMsg) throws GopayException {
		// TODO Auto-generated method stub
		return null;
	}

	public CiticExpayCertHelper getCiticExpayCertHelper() {
		return citicExpayCertHelper;
	}

	public void setCiticExpayCertHelper(CiticExpayCertHelper citicExpayCertHelper) {
		this.citicExpayCertHelper = citicExpayCertHelper;
	}

}
